#include "TurnGenerator.h"
#include "ZStream.h"

#include <vector>
#include <list>
#include <iostream>

void TurnGenerator::GetTurnNumber(const unsigned int i_turn_numb,Couples& o_out)  const 
{
	const unsigned int isize(m_data.size());
	assert(i_turn_numb < 2*isize);

	const unsigned int turn_numb=m_scramble[i_turn_numb];
	assert(turn_numb < 2*isize);

	if (turn_numb<isize) 
	{
		o_out= m_data[turn_numb];
	}
	else
	{
		Couples coup;
		for (unsigned int i=0;i<=(isize/2);++i)
		{
			Couple c(m_data[turn_numb-isize][i].second,m_data[turn_numb-isize][i].first);
			coup.push_back(c);
		}
		o_out = coup;
	}
	
}

void TurnGenerator::Clear()
{
	m_data.clear();
	m_scramble.clear();
}

void TurnGenerator::Initialize(const size_t i_numTeams)
{
	using namespace std;
	vector<int> teamvec;
	
	for (unsigned int i=0;i<i_numTeams;++i)
	{
		teamvec.push_back(i);
	}
	
	//step 1:built the half m_data using roundrobin algorithm
	Couples coup;
	
	m_data.clear();
	for (unsigned int j=0;j<i_numTeams-1;++j)
	{
		for (unsigned int i=0;i<i_numTeams/2;++i)
		{
			Couple c(teamvec[i],teamvec[-1+i_numTeams-i]);
			coup.push_back(c);
		}
		m_data.push_back (coup);
		coup.clear();
		int last=teamvec[i_numTeams-1];
		vector<int>::iterator it= teamvec.begin()+1;
		teamvec.insert(it,last);
		teamvec.pop_back();
		//cout<<endl;
	}
	
	//step 2:built the scrambling vector
	unsigned int size=(2*(i_numTeams-1));
	
	m_scramble.clear();
	for (unsigned int i=0;i<size;++i)
		m_scramble.push_back(i);
	
	//size/=2;

	for (unsigned int i=0;i<size;++i)
	{
		if (rand()%100<50)
		{
			int primo=i;
			int secondo=((size/2)+i)%size;
			int temp = m_scramble[primo];
			m_scramble[primo] = m_scramble[secondo];
			m_scramble[secondo] = temp;
		}	
		/*
		temp = m_scramble[size+primo];
		m_scramble[size+primo] = m_scramble[size+secondo];
		m_scramble[size+secondo] = temp;
		*/

	}
}

ZStream& TurnGenerator::Serialize(ZStream& o_stream)
{
	std::vector<Couples>::iterator it = m_data.begin();
	std::vector<Couples>::iterator end = m_data.end();

	o_stream.WriteAttribute("Scramble", m_scramble);

	for(; it != end; ++it)
	{
		o_stream.WriteAttribute("Day", (*it));
	}

	return o_stream;
}

ZStream& TurnGenerator::Deserialize(ZStream& i_stream)
{
	m_scramble.clear();
	m_data.clear();

	i_stream.ReadAttribute(m_scramble);
	size_t size = m_scramble.size() / 2;

	for(size_t i = 0; i < size; ++i)
	{
		Couples couples;
		i_stream.ReadAttribute(couples);
		m_data.push_back(couples);
	}

	return i_stream;
}

/*void TestTurnSystem()
{
	typedef TurnGenerator::Couples::iterator It;

	TurnGenerator t;
	TurnGenerator::Couples temp;
	for (int i=0;i<(NUM_TEAMS-1)*2;++i)
	{
		t.GetTurnNumber(i,temp);
		
		It begin=temp.begin();
		It end=temp.end();
		for (It scan=begin;scan!=end;++scan)
		{
			std::cout << "(" << scan->first << "," << scan->second  << ") " ;
		}
		std::cout << std::endl;
	}
}*/
